import { ElMessage, ElMessageBox } from 'element-plus'
import type { MessageType, MessageOptions } from 'element-plus'

/**
 * 消息队列项接口
 */
interface MessageQueueItem {
  id: string
  type: MessageType
  message: string
  options?: MessageOptions
  timestamp: number
  priority: number // 优先级，数字越小优先级越高
}

/**
 * 消息队列管理器
 * 实现消息队列化，防止过多消息同时显示
 */
class MessageQueueManager {
  private queue: MessageQueueItem[] = []
  private activeMessages: Set<string> = new Set()
  private maxConcurrentMessages = 3 // 最多同时显示2个消息
  private messageTimeout = 3000 // 消息默认显示时间
  private nextId = 1

  /**
   * 添加消息到队列
   */
  private addToQueue(
    type: MessageType,
    message: string,
    options?: MessageOptions,
    priority: number = 5
  ): string {
    const id = `msg_${this.nextId++}`
    const queueItem: MessageQueueItem = {
      id,
      type,
      message,
      options: {
        duration: this.messageTimeout,
        ...options
      },
      timestamp: Date.now(),
      priority
    }

    // 按优先级插入队列
    const insertIndex = this.queue.findIndex(item => item.priority > priority)
    if (insertIndex === -1) {
      this.queue.push(queueItem)
    } else {
      this.queue.splice(insertIndex, 0, queueItem)
    }

    // 尝试处理队列
    this.processQueue()
    
    return id
  }

  /**
   * 处理消息队列
   */
  private processQueue(): void {
    // 如果当前显示的消息数量已达到上限，则等待
    if (this.activeMessages.size >= this.maxConcurrentMessages) {
      return
    }

    // 获取下一个要显示的消息
    const nextMessage = this.queue.shift()
    if (!nextMessage) {
      return
    }

    // 显示消息
    this.showMessage(nextMessage)
  }

  /**
   * 显示消息
   */
  private showMessage(queueItem: MessageQueueItem): void {
    const { id, type, message, options } = queueItem
    
    // 添加到活跃消息集合
    this.activeMessages.add(id)

    // 显示消息
    const messageInstance = ElMessage({
      type,
      message,
      duration: options?.duration || this.messageTimeout,
      ...options,
      onClose: () => {
        // 消息关闭时从活跃集合中移除
        this.activeMessages.delete(id)
        // 继续处理队列
        this.processQueue()
      }
    })

    // 如果设置了duration，自动处理队列
    if (options?.duration !== 0) {
      setTimeout(() => {
        this.activeMessages.delete(id)
        this.processQueue()
      }, options?.duration || this.messageTimeout)
    }
  }

  /**
   * 显示成功消息
   */
  success(message: string, options?: MessageOptions): string {
    return this.addToQueue('success', message, options, 1)
  }

  /**
   * 显示错误消息
   */
  error(message: string, options?: MessageOptions): string {
    return this.addToQueue('error', message, options, 2)
  }

  /**
   * 显示警告消息
   */
  warning(message: string, options?: MessageOptions): string {
    return this.addToQueue('warning', message, options, 3)
  }

  /**
   * 显示信息消息
   */
  info(message: string, options?: MessageOptions): string {
    return this.addToQueue('info', message, options, 4)
  }

  /**
   * 显示普通消息
   */
  message(message: string, options?: MessageOptions): string {
    return this.addToQueue('', message, options, 5)
  }

  /**
   * 清空队列
   */
  clearQueue(): void {
    this.queue = []
    // 关闭所有活跃的消息
    ElMessage.closeAll()
    this.activeMessages.clear()
  }

  /**
   * 获取队列状态
   */
  getQueueStatus(): {
    queueLength: number
    activeMessages: number
    maxConcurrent: number
  } {
    return {
      queueLength: this.queue.length,
      activeMessages: this.activeMessages.size,
      maxConcurrent: this.maxConcurrentMessages
    }
  }

  /**
   * 设置最大并发消息数
   */
  setMaxConcurrentMessages(max: number): void {
    this.maxConcurrentMessages = Math.max(1, max)
    // 如果当前活跃消息数超过新的限制，处理队列
    this.processQueue()
  }

  /**
   * 设置消息默认显示时间
   */
  setMessageTimeout(timeout: number): void {
    this.messageTimeout = Math.max(0, timeout)
  }

  /**
   * 批量显示消息（用于调试或特殊场景）
   */
  batchShow(messages: Array<{ type: MessageType; message: string; options?: MessageOptions }>): void {
    messages.forEach(({ type, message, options }) => {
      this.addToQueue(type, message, options)
    })
  }
}

// 创建全局实例
const messageQueue = new MessageQueueManager()

/**
 * 消息队列代理对象
 * 提供与原 ElMessage 相同的 API，但通过队列管理
 */
export const MessageQueue = {
  success: (message: string, options?: MessageOptions) => messageQueue.success(message, options),
  error: (message: string, options?: MessageOptions) => messageQueue.error(message, options),
  warning: (message: string, options?: MessageOptions) => messageQueue.warning(message, options),
  info: (message: string, options?: MessageOptions) => messageQueue.info(message, options),
  message: (message: string, options?: MessageOptions) => messageQueue.message(message, options),
  
  // 队列管理方法
  clearQueue: () => messageQueue.clearQueue(),
  getQueueStatus: () => messageQueue.getQueueStatus(),
  setMaxConcurrentMessages: (max: number) => messageQueue.setMaxConcurrentMessages(max),
  setMessageTimeout: (timeout: number) => messageQueue.setMessageTimeout(timeout),
  batchShow: (messages: Array<{ type: MessageType; message: string; options?: MessageOptions }>) => 
    messageQueue.batchShow(messages)
}

/**
 * 消息拦截器
 * 自动拦截所有 ElMessage 调用并重定向到队列管理器
 */
export function interceptElMessage(): void {
  // 保存原始的 ElMessage 方法
  const originalElMessage = { ...ElMessage }

  // 重写 ElMessage 的方法
  Object.keys(MessageQueue).forEach(method => {
    if (typeof MessageQueue[method as keyof typeof MessageQueue] === 'function') {
      (ElMessage as any)[method] = (MessageQueue as any)[method]
    }
  })

  // 保留 ElMessage.closeAll 等管理方法
  ElMessage.closeAll = originalElMessage.closeAll

  console.log('ElMessage 已成功拦截并重定向到消息队列管理器')
}

/**
 * 恢复原始 ElMessage
 */
export function restoreElMessage(): void {
  // 重新导入 ElementPlus 来恢复原始方法
  import('element-plus').then(({ ElMessage: OriginalElMessage }) => {
    Object.assign(ElMessage, OriginalElMessage)
    console.log('ElMessage 已恢复到原始状态')
  })
}

export default MessageQueue
